{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy.io\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## read data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "data_path = 'data/joke_data/'\n",
    "train = scipy.io.loadmat(data_path + 'joke_train.mat')\n",
    "train = train['train']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3690, 3)\n"
     ]
    }
   ],
   "source": [
    "file = open(data_path + 'validation.txt')\n",
    "data = file.read()\n",
    "data = data.split('\\n')\n",
    "validation = []\n",
    "for i in data[:-1]:\n",
    "    ii = list(map(int, i.split(',')))\n",
    "    validation.append(ii)\n",
    "validation = np.array(validation)\n",
    "print(validation.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(902409, 3)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "file = open(data_path + 'query.txt')\n",
    "data = file.read()\n",
    "data = data.split('\\n')\n",
    "query = []\n",
    "for i in data[:-1]:\n",
    "    ii = list(map(int, i.split(',')))\n",
    "    query.append(ii)\n",
    "query = np.array(query)\n",
    "query.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Latent factor model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def evaluate_zf_MSE(R, d):\n",
    "    Rzf = np.nan_to_num(R)\n",
    "    u, s, v = np.linalg.svd(Rzf, full_matrices=0)\n",
    "    users = np.multiply(u[:, :d], np.sqrt(s[:d]))\n",
    "    items = np.multiply(v[:d, :].T, np.sqrt(s[:d])).T\n",
    "    Rapprox = users.dot(items)\n",
    "    diff = np.square(Rapprox - Rzf)\n",
    "    idx = np.logical_not(np.isnan(R))\n",
    "    MSE = np.sum(diff[idx]) / np.sum(idx)\n",
    "    return users, items, MSE\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "def validation_accuracy(users, items, validation):\n",
    "    N = len(validation)\n",
    "    Ncorrect = 0\n",
    "    for i in validation:\n",
    "        predict = users[i[0]-1, :].dot(items[:, i[1]-1])\n",
    "        if predict * (i[2]-0.5) > 0:\n",
    "            Ncorrect += 1\n",
    "    return Ncorrect/float(N)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "d=2, validation accuracy=0.705149\n",
      "d=5, validation accuracy=0.715447\n",
      "d=10, validation accuracy=0.716531\n",
      "d=20, validation accuracy=0.685908\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1e620b749e8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "all_d = [2, 5, 10, 20]\n",
    "MSE = np.zeros(len(all_d))\n",
    "for i, d in enumerate(all_d):\n",
    "    users, items, MSE[i] = evaluate_zf_MSE(train, d)\n",
    "    print('d=%d, validation accuracy=%f' % (d, validation_accuracy(users, items, validation)))\n",
    "plt.plot(all_d, MSE)\n",
    "plt.xlabel('d')\n",
    "plt.ylabel('MSE')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nWfEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1e61ce58be0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot for (b)\n",
    "plt.plot([2, 5, 10, 20], [13.4490305364077, 15.3115781030497, 18.7490313967159, 25.5368811320869])\n",
    "plt.xlabel('d')\n",
    "plt.ylabel('MSE')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
